package cn.xiaopengstack.types.utils;

import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.*;

/**
 * @author jiangyangang
 */
public class TimeUtils {

    public static final String YYYYMMDD = "yyyyMMdd";

    public static final String YYYY_MM_DD = "yyyy-MM-dd";
    public static final String YYYY_MM = "yyyy-MM";

    public static final String DD_MM_YYYY = "dd-MM-yyyy";

    public static final String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";

    public static final String YYYYMMDDHHMM="yyyyMMddHHmm";

    public static final String MMDD = "MMdd";

    public static final String FULL_DATE_TIME_FORMAT_IN = "dd-MM-yyyy HH:mm:ss:SS";

    public static final String SIMPLE_DATE_TIME = "yyyyMMdd HH:mm:ss";
    public static final String SIMPLE_DATE_TIME_MILLI = "yyyyMMdd HH:mm:ss SSS";

    public static final String MMDDYYYY = "MM/dd/yyyy";

    public static final String YYYY_MM_DD_HHMMSS = "yyyy-MM-dd HH:mm:ss";


    /**
     * 获取当前时间
     * @param format 格式
     * @return
     */
    public static String getNowDateTime(String format){
        return LocalDateTime.now().format(DateTimeFormatter.ofPattern(format));
    }

    /**
     * 获取当前结束的时间
     * @param format
     * @return
     */
    public static String getTodayEndTime(String format){
        LocalDate nowDate = LocalDate.now();
        LocalTime maxDayTime = LocalTime.of(23, 59, 59);
        return LocalDateTime.of(nowDate, maxDayTime).format(DateTimeFormatter.ofPattern(format));

        /*
        LocalDateTime localDateTime = LocalDateTime.now().toLocalDate().atTime(LocalTime.MAX);
        return localDateTime.format(DateTimeFormatter.ofPattern(format));
        */
    }

    /**
     * 计算当天还有多少秒结束
     * @return
     */
    public static long getSecondOfDayEnd(){
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime endOfDay = now.toLocalDate().atTime(LocalTime.MAX);

        return Duration.between(now, endOfDay).getSeconds();
    }

    /**
     * 计算当天还有多少毫秒结束
     * @return
     */
    public static long getMsOfDayEnd(){
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime endOfDay = now.toLocalDate().atTime(LocalTime.MAX);

        return Duration.between(now, endOfDay).toMillis();
    }

    /**
     * 计算当天还有多少毫秒结束
     * @return
     */
    public static long getLocalZoneTimeToMs(){
        LocalDateTime now = LocalDateTime.now();
        return now.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
    }

    /**
     * 计算两天时间的天数差
     * @param startTime
     * @param endTime
     * @return
     */
    public static long getDayBetween(LocalDateTime startTime, LocalDateTime endTime){
        return Duration.between(startTime, endTime).get(ChronoUnit.DAYS);
    }

    /**
     * 获取当天开始时间
     * @param format
     * @return
     */
    public static String getNowTimeStart(String format){
        LocalDate now = LocalDate.now();
        LocalDateTime localDateTime = now.atStartOfDay();
        return localDateTime.format(DateTimeFormatter.ofPattern(format));
    }

    /**
     * 获取当天开始时间，毫秒数
     * @return
     */
    public static long getNowTimeStartToMs(){
        LocalDateTime now = LocalDateTime.of(LocalDate.now(), LocalTime.MIN);
        return now.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
    }

    /**
     * 时间字符串转为LocalDateTime
     * @param dateStr
     * @param format
     * @return
     */
    public static LocalDateTime strToLocalDateTime(String dateStr, String format){
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(format);
        return LocalDateTime.parse(dateStr, dateTimeFormatter);
    }

    /**
     * Date 对象转为LocalDateTime
     * @param date
     * @return
     */
    public static LocalDateTime dateToLocal(Date date){
        ZonedDateTime zonedDateTime = date.toInstant().atZone(ZoneId.systemDefault());
        return zonedDateTime.toLocalDateTime();
    }

    /**
     * date转为字符串
     * @param date
     * @param format
     * @return
     */
    public static String dateToString(Date date, String format) {
        ZonedDateTime zonedDateTime = date.toInstant().atZone(ZoneId.systemDefault());
        return zonedDateTime.toLocalDateTime().format(DateTimeFormatter.ofPattern(format));
    }

    /**
     * 获取当天是几月几号 几时 几分 几秒
     * @param timeUnits 时间单元集合
     */
    public static Map<TimeUnit, String> getManualDateFromNow(TimeUnit... timeUnits){
        LocalDateTime now = LocalDateTime.now();
        return getTimeUnitStringHashMap(timeUnits, now);
    }

    private static HashMap<TimeUnit, String> getTimeUnitStringHashMap(TimeUnit[] timeUnits, LocalDateTime date) {
        HashMap<TimeUnit, String> dateMap = new HashMap<>(8);
        for (TimeUnit timeUnit : timeUnits) {
            switch (timeUnit){
                case YEAR:
                    dateMap.put(TimeUnit.YEAR, String.valueOf(date.getYear()));
                    break;
                case MONTH:
                    dateMap.put(TimeUnit.MONTH, String.valueOf(date.getMonth()));
                    break;
                case DAY:
                    dateMap.put(TimeUnit.DAY, String.valueOf(date.getDayOfMonth()));
                    break;
                case HOUR:
                    dateMap.put(TimeUnit.HOUR, String.valueOf(date.getHour()));
                    break;
                case MINUTE:
                    dateMap.put(TimeUnit.MINUTE, String.valueOf(date.getMinute()));
                    break;
                case SECOND:
                    dateMap.put(TimeUnit.SECOND, String.valueOf(date.getSecond()));
                    break;
                case WEEK:
                    dateMap.put(TimeUnit.WEEK, String.valueOf(date.getDayOfWeek()));
                    break;
                default:
                    break;
            }
        }
        return dateMap;
    }


    public static void main(String[] args) {
        /*LocalDateTime now1 = LocalDateTime.now();
        DateTimeFormatter dateTimeFormatter1 = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM);
        LocalDateTime now2 = LocalDateTime.now();
        DateTimeFormatter dateTimeFormatter2 = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.LONG, FormatStyle.MEDIUM);
        LocalDateTime now3 = LocalDateTime.now();
        DateTimeFormatter dateTimeFormatter3 = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT);

        System.out.println(now1.format(dateTimeFormatter1));
        System.out.println(now2.format(dateTimeFormatter2));
        System.out.println(now3.format(dateTimeFormatter3));*/
        System.out.println( getNowTimeStartToMs());

        // LocalDateTime 的加减
        LocalDateTime now = LocalDateTime.now();
        // 加一年
        LocalDateTime nowAddOneYear = now.plusYears(1L);
        // 加一个月
        LocalDateTime nowAddOneMonth = now.plusMonths(1L);
        // 加一天
        LocalDateTime nowAddOneDay = now.plusDays(1L);
        // 加一个小时
        LocalDateTime nowAddOneHour = now.plusHours(1L);
        // 加一分钟
        LocalDateTime nowAddOneMin = now.plusMinutes(1);

    }

    /**
     * 获取当前的天数
     * @return
     */
    public static String getDayByNow() {
        return getManualDateFromNow(TimeUnit.DAY).get(TimeUnit.DAY);
    }

    /**
     * 获取当前的月份
     * @return
     */
    public static String getMonthByNow() {
        return getManualDateFromNow(TimeUnit.MONTH).get(TimeUnit.MONTH);
    }

    public static String getDayByTime(Long rechargeTime) {
        Date date = new Date(rechargeTime);
        LocalDateTime localDateTime = LocalDateTime.ofInstant(date.toInstant(), ZoneOffset.systemDefault());
        return getTimeUnitStringHashMap(new TimeUnit[]{TimeUnit.DAY}, localDateTime).get(TimeUnit.DAY);
    }

    public static String getMonthByTime(Long rechargeTime) {
        Date date = new Date(rechargeTime);
        LocalDateTime localDateTime = LocalDateTime.ofInstant(date.toInstant(), ZoneOffset.systemDefault());
        return getTimeUnitStringHashMap(new TimeUnit[]{TimeUnit.MONTH}, localDateTime).get(TimeUnit.MONTH);
    }

    /**
     * 时间单位
     */
    public enum TimeUnit{
        YEAR,
        MONTH,
        DAY,
        WEEK,
        HOUR,
        MINUTE,
        SECOND
    }

}
